package com.rpc.spring;

import com.rpc.annotation.RpcClient;
import com.rpc.annotation.RpcService;
import com.rpc.common.ChannelMaps;
import com.rpc.config.RpcServiceConfig;
import com.rpc.handler.RpcClientHandler;
import com.rpc.proxy.ProxyFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;

import java.lang.reflect.Field;

public class SpringBeanPostProcessor implements BeanPostProcessor {
    @Autowired
    private RpcClientHandler rpcClientHandler;

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean.getClass().isAnnotationPresent(RpcService.class)) {
            RpcService rpcService = bean.getClass().getAnnotation(RpcService.class);
            RpcServiceConfig rpcServiceConfig = new RpcServiceConfig(rpcService.version(),rpcService.group(),bean);
            ChannelMaps.putRpcServiceConfig(rpcServiceConfig);
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        Class<?> targetClass = bean.getClass();
        Field[] declaredFields = targetClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            RpcClient rpcClient = declaredField.getAnnotation(RpcClient.class);
            if (rpcClient != null) {
                RpcServiceConfig rpcServiceConfig = new RpcServiceConfig(rpcClient.version(),rpcClient.group());
                Object proxy = ProxyFactory.getProxy(declaredField.getType(), rpcClientHandler,rpcClient.server(),rpcServiceConfig);
                declaredField.setAccessible(true);
                try {
                    declaredField.set(bean, proxy);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
        return bean;
    }

}
